package com.ant.storage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ant.storage.dto.DictionaryDto;
import com.ant.storage.excel.JsonNode;
import com.ant.storage.mapper.DictionaryMapper;
import com.ant.storage.pojo.Dictionary;
import com.ant.storage.service.IDictionaryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hzd
 * @since 2025-10-23
 */
@Service
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, Dictionary> implements IDictionaryService {

    @Override
    public Dictionary saveDictionary(DictionaryDto dto) {
        Dictionary dic = new Dictionary();
        dic.setParentId(dto.getParentId());
        dic.setDicName(dto.getDicName().trim());
        dic.setDicValue(dto.getDicValue().trim());
        dic.setDicCraft(dto.getDicCraft());
        dic.setDicType(dto.getDicType().trim());
        if (dto.getId() == null) {
            baseMapper.insert(dic);
        } else {
            dic.setId(dto.getId());
            baseMapper.updateById(dic);
        }
        return dic;
    }

//    @Override
//    public List<Dictionary> listTree() {
//        // 1. 查询所有符合条件的字典数据（也可分页，视需求而定）
//        List<Dictionary> dicList = baseMapper.selectList(new QueryWrapper<>().eq("",)); // 自定义方法：按类型查询
//        // 2. 筛选顶级节点（parentId = 0 或 null）
//        List<Dictionary> topNodes = dicList.stream()
//                .filter(dic -> dic.getParentId() == null || dic.getParentId() == 0)
//                .collect(Collectors.toList());
//
//        // 3. 为每个顶级节点递归设置子节点
//        for (Dictionary topNode : topNodes) {
//            setChildren(topNode, dicList);
//        }
//        return topNodes;
//    }


    /**
     * 递归查询指定类型的字典树形结构
     *
     * @param dicType 字典类型（可选，用于过滤特定类型）
     * @return 树形结构的字典列表
     */
    public List<Dictionary> listTree(String dicType) {

        // 1. 查询所有符合条件的字典数据（也可分页，视需求而定）
        List<Dictionary> dicList = baseMapper.selectList(new QueryWrapper<Dictionary>()
                .eq("dic_type", dicType)); // 自定义方法：按类型查询
        // 2. 筛选顶级节点（parentId = 0 或 null）
        List<Dictionary> topNodes = dicList.stream()
                .filter(dic -> dic.getParentId() == null || dic.getParentId() == 0)
                .collect(Collectors.toList());

        // 3. 为每个顶级节点递归设置子节点
        for (Dictionary topNode : topNodes) {
            setChildren(topNode, dicList);
        }
        return topNodes;

    }


    /**
     * 递归为节点设置子节点
     *
     * @param parentNode 父节点
     * @param allDics    所有字典数据（避免多次查询数据库）
     */
    private void setChildren(Dictionary parentNode, List<Dictionary> allDics) {
        // 筛选当前父节点的子节点（parentId = 父节点 id）
        List<Dictionary> children = allDics.stream()
                .filter(dic -> parentNode.getId().equals(dic.getParentId()))
                .collect(Collectors.toList());

        // 若有子节点，继续递归设置子节点的子节点
        if (!children.isEmpty()) {
            parentNode.setChildren(children);
            for (Dictionary child : children) {
                setChildren(child, allDics); // 递归
            }
        }
    }
//
//    /**
//     * 解析JSON字符串并保存到数据库
//     *
//     * @param jsonStr 嵌套JSON字符串
//     * @param dicType 字典类型（自定义，如"org_type"）
//     */
//    @Transactional
//    public void saveFromJson(String jsonStr, String dicType) {
//        // 1. 将JSON字符串解析为根节点
//        JsonNode rootNode = JSON.parseObject(jsonStr, JsonNode.class);
//        // 2. 递归保存所有节点（根节点的parentId为null）
//        saveNode(rootNode, null, dicType);
//    }
//
//    /**
//     * 递归保存节点及其子节点
//     *
//     * @param node     当前JSON节点
//     * @param parentId 父级ID（上级节点的id）
//     * @param dicType  字典类型
//     */
//    private void saveNode(JsonNode node, Integer parentId, String dicType) {
//        if (node == null) {
//            return;
//        }
//        // 3. 转换为数据库实体对象
//        Dictionary dictionary = new Dictionary();
//        dictionary.setParentId(parentId); // 下级的parentId=上级的id
//        dictionary.setDicName(node.getName()); // 对应JSON的name
//        dictionary.setDicValue(node.getCode()); // 对应JSON的code
//        dictionary.setDicType(dicType); // 自定义字典类型
//
//        // 4. 保存当前节点到数据库（MyBatis-Plus会自动回填自增id）
//        baseMapper.insert(dictionary);
//
//        // 5. 递归保存子节点（子节点的parentId=当前节点的id）
//        List<JsonNode> children = node.getChildren();
//        if (children != null && !children.isEmpty()) {
//            for (JsonNode child : children) {
//                // 传入当前节点的id作为子节点的parentId
//                saveNode(child, dictionary.getId(), dicType);
//            }
//        }
//    }
//
//
//    /**
//     * 从JSON文件读取数据并保存到数据库
//     *
//     * @param fileName JSON文件路径（如classpath:data.json）
//     * @param dicType  字典类型（自定义，如"international_org"）
//     */
//    @Transactional
//    public void saveFromJsonFile(String fileName, String dicType) throws Exception {
//        // 1. 读取JSON文件内容为字符串
//        String jsonContent = readJsonFile(fileName);
//        // 2. 解析JSON为根节点对象
//        JsonNode rootNode = JSON.parseObject(jsonContent, JsonNode.class);
//        // 3. 递归保存所有节点（根节点parentId为null）
//        saveNodeRecursively(rootNode, null, dicType);
//    }
//
//    /**
//     * 读取JSON文件内容
//     */
//    private String readJsonFile(String fileName) throws Exception {
//        // 从类路径下读取文件（如src/main/resources/data.json）
//        ClassPathResource resource = new ClassPathResource(fileName);
//        try (InputStream is = resource.getInputStream()) {
//            byte[] bytes = new byte[is.available()];
//            is.read(bytes);
//            return new String(bytes, StandardCharsets.UTF_8);
//        }
//    }
//
//    /**
//     * 递归保存节点及其子节点，设置parentId
//     *
//     * @param node     当前节点
//     * @param parentId 父节点ID（上级id）
//     * @param dicType  字典类型
//     */
//    private void saveNodeRecursively(JsonNode node, Integer parentId, String dicType) {
//        if (node == null) return;
//
//        // 转换为数据库实体
//        Dictionary dict = new Dictionary();
//        dict.setParentId(parentId); // 子节点的parentId=父节点id
//        dict.setDicName(node.getName());
//        dict.setDicValue(node.getCode());
//        dict.setDicType(dicType);
//
//        // 保存当前节点（MyBatis-Plus自动回填自增id）
//        baseMapper.insert(dict);
//
//        // 递归保存子节点（子节点的parentId=当前节点的id）
//        List<JsonNode> children = node.getChildren();
//        if (children != null && !children.isEmpty()) {
//            for (JsonNode child : children) {
//                saveNodeRecursively(child, dict.getId(), dicType);
//            }
//        }
//    }

    @Autowired
    private ObjectMapper objectMapper;

    // 导入行业数据，设置dicType为"industry"
    @Transactional
    public void importIndustryData(String filePath) throws Exception {
        // 读取JSON文件并解析为节点列表
        // 从classpath获取文件流（无需绝对路径）
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath);
        if (inputStream == null) {
            throw new FileNotFoundException("资源文件不存在：" + filePath);
        }

        List<JsonNode> rootNodes = objectMapper.readValue(
                inputStream,
                new TypeReference<List<JsonNode>>() {
                }
        );

        // 递归保存所有节点，顶级节点parentId为null，类型为"industry"
        for (JsonNode root : rootNodes) {
            saveNode(root, null, "industry");
        }
    }

    // 递归保存节点及其子节点
    private void saveNode(JsonNode node, Integer parentId, String dicType) {
        Dictionary dict = new Dictionary();
        dict.setId(node.getId());
        dict.setParentId(parentId);
        dict.setDicName(node.getName()); // name -> dicName
        dict.setDicValue(node.getCode()); // code -> dicValue
        dict.setDicType(dicType); // 设置字典类型

        // 保存当前节点
        baseMapper.insert(dict);
        // 递归保存子节点（子节点的parentId为当前节点id）
        if (node.getChildren() != null && !node.getChildren().isEmpty()) {
            for (JsonNode child : node.getChildren()) {
                saveNode(child, node.getId(), dicType);
            }
        }
    }


    /**
     * 从JSON文件导入数据到数据库
     */
    public void importFromJsonFile() {
        try {
            // 读取JSON文件
            File file = ResourceUtils.getFile("classpath:4.json");
            String content = new String(Files.readAllBytes(file.toPath()));
            // 解析JSON
            JSONArray jsonArray = JSON.parseArray(content);
            // 处理数据
            List<Dictionary> dictionaries = new ArrayList<>();
            processJsonArray(jsonArray, null, dictionaries, "1234");
            // 批量保存到数据库
            for (Dictionary dict : dictionaries) {
                baseMapper.insert(dict);
            }
            System.out.println("成功导入 " + dictionaries.size() + " 条数据");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 递归处理JSON数组
     *
     * @param jsonArray  JSON数组
     * @param parentId   父级ID
     * @param resultList 结果列表
     * @param dicType    字典类型
     */
    private void processJsonArray(JSONArray jsonArray, Integer parentId,
                                  List<Dictionary> resultList, String dicType) {
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject obj = jsonArray.getJSONObject(i);

            // 创建字典对象
            Dictionary dict = new Dictionary();
            dict.setId(obj.getInteger("id"));
            dict.setParentId(parentId);
            dict.setDicName(obj.getString("name"));
            dict.setDicValue(obj.getString("code"));
            dict.setDicType(dicType);

            resultList.add(dict);

            // 递归处理子节点
            if (obj.containsKey("children") && obj.getJSONArray("children") != null) {
                JSONArray children = obj.getJSONArray("children");
                processJsonArray(children, obj.getInteger("id"), resultList, dicType);
            }
        }
    }

    /**
     * 从JSON字符串导入数据
     */
    public void importFromJsonString(String jsonString) {
        try {
            JSONArray jsonArray = JSON.parseArray(jsonString);
            List<Dictionary> dictionaries = new ArrayList<>();
            processJsonArray(jsonArray, null, dictionaries, "industry");

            for (Dictionary dict : dictionaries) {
                baseMapper.insert(dict);
            }

            System.out.println("成功导入 " + dictionaries.size() + " 条数据");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//
//    ////////
//    public void importExcelData(MultipartFile file) {
//        try {
//            Workbook workbook = WorkbookFactory.create(file.getInputStream());
//            Sheet sheet = workbook.getSheetAt(0);
//
//            // 存储临时映射关系：originalCode -> newId
//            Map<String, Long> codeToIdMap = new HashMap<>();
//            // 存储层级关系
//            Map<Integer, String> levelCodeMap = new HashMap<>();
//
//            int rowNum = 0;
//            for (Row row : sheet) {
//                if (rowNum == 0) { // 跳过表头
//                    rowNum++;
//                    continue;
//                }
//
//                // 解析每一列
//                String colA = getCellStringValue(row.getCell(0)); // A列
//                String colB = getCellStringValue(row.getCell(1)); // B列
//                String colC = getCellStringValue(row.getCell(2)); // C列
//                String colD = getCellStringValue(row.getCell(3)); // D列
//                String name = getCellStringValue(row.getCell(4)); // E列
//
//                // 确定当前行的originalCode和层级
//                String currentCode = null;
//                Integer level = null;
//                Long parentId = null;
//
//                if (!colD.isEmpty()) {
//                    currentCode = colD;
//                    level = 4;
//                    parentId = codeToIdMap.get(colC);
//                } else if (!colC.isEmpty()) {
//                    currentCode = colC;
//                    level = 3;
//                    parentId = codeToIdMap.get(colB);
//                } else if (!colB.isEmpty()) {
//                    currentCode = colB;
//                    level = 2;
//                    parentId = codeToIdMap.get(colA);
//                } else if (!colA.isEmpty()) {
//                    currentCode = colA;
//                    level = 1;
//                    parentId = null;
//                } else {
//                    continue; // 跳过空行
//                }
//
//                // 保存到数据库
//                IndustryCategory category = new IndustryCategory(name, parentId, currentCode, level);
//                //IndustryCategory saved = repository.save(category);
//
//                // 更新映射关系
//               // codeToIdMap.put(currentCode, saved.getId());
//
//                rowNum++;
//            }
//
//            workbook.close();
//           // log.info("成功导入 {} 条行业分类数据", rowNum - 1);
//
//        } catch (Exception e) {
//            log.error("导入Excel数据失败", e);
//            throw new RuntimeException("导入失败: " + e.getMessage());
//        }
//    }
//
//    private String getCellStringValue(Cell cell) {
//        if (cell == null) {
//            return "";
//        }
//
//        switch (cell.getCellType()) {
//            case STRING:
//                return cell.getStringCellValue().trim();
//            case NUMERIC:
//                if (DateUtil.isCellDateFormatted(cell)) {
//                    return cell.getDateCellValue().toString();
//                } else {
//                    return String.valueOf((long) cell.getNumericCellValue());
//                }
//            case BOOLEAN:
//                return String.valueOf(cell.getBooleanCellValue());
//            case FORMULA:
//                return cell.getCellFormula();
//            default:
//                return "";
//        }
//    }

}
